#include "httpclient.h"

namespace Http
{
	HttpClient::HttpClient(std::string url):m_url(url)
	{
		m_exit = false;

	}

	HttpClient::HttpClient(std::string url, std::map<Http::HTTP_HEAD_KEY, Http::HTTP_HEAD_VALUE> headers) :m_url(url),
		m_headers(headers),
		m_exit(false)
	{

	}

	HttpClient::~HttpClient()
	{

	}

	// 处理回执消息
	void HttpClient::replay(mg_connection *connection, int event_type, void *event_data)
	{
		HttpClient *p_this = (HttpClient *)connection->mgr->mg_this;
		if (p_this == nullptr)
		{
			return;
		}

		http_message *hm = (struct http_message *)event_data;
		int connect_status;

		switch (event_type)
		{
		case MG_EV_CONNECT:
			connect_status = *(int *)event_data;
			if (connect_status != 0)
			{
				Log::printError("Error connecting to server, error code: "+ std::to_string( connect_status)+"  "+p_this->m_url);
				p_this->m_exit = true;
			}
			break;
		case MG_EV_HTTP_REPLY:
		{
			std::string rsp = std::string(hm->body.p, hm->body.len);
			connection->flags |= MG_F_SEND_AND_CLOSE;
			p_this->m_exit = true; // 每次收到请求后关闭本次连接，重置标记
			
			if (p_this->p_req_callback != nullptr)
			{
				p_this->p_req_callback((char *)hm->body.p, hm->body.len);
			}
		}
		break;
		case MG_EV_CLOSE: {
			if (!p_this->m_exit)
			{
				Log::printInfo("Server closed connection url:" + p_this->m_url);
				p_this->m_exit = true;
			};
		};break;
		case MG_EV_TIMER: {
			if (!p_this->m_exit)
			{
				Log::printInfo("Server connec timeout url:" + p_this->m_url);
				p_this->m_exit = true;
			}
		}; break;
		default:
			break;
		}
	}
	 
	bool HttpClient::send(char *data, size_t len, reqCallback req_callback)
	{
		p_req_callback = req_callback;

		mg_mgr mgr;
		mg_mgr_init(&mgr, NULL);
		// 注册一下本地的this指针
		mgr.mg_this = this;

		std::string strheaders;
		for (auto it = m_headers.begin();
			it != m_headers.end();
			it++)
		{
			strheaders += it->first + ":" + it->second + "\n";
		}

		auto connection = mg_connect_http(&mgr, HttpClient::replay, m_url.data(),strheaders.size() == 0 ? nullptr: strheaders.data(), data);
		mg_set_protocol_http_websocket(connection);

		Log::printInfo("Send http request " + m_url);

		// loop
		while (!m_exit)
			mg_mgr_poll(&mgr, 500);

		mg_mgr_free(&mgr);
		return true;
	}
}